package cheme.ProcessEditor.Parts.Equations;

import java.util.List;

import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.Request;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.commands.CompoundCommand;
import org.eclipse.gef.requests.ChangeBoundsRequest;
import org.eclipse.gef.requests.CreateRequest;

import cheme.ProcessEditor.Policies.ToolbarLayoutEditPolicy;
import cheme.ProcessModel.IChild;
import cheme.ProcessModel.IParent;
import cheme.ProcessModel.SolvabilityStatus;
import cheme.ProcessModel.TooltipModel;
import cheme.ProcessModel.Cmds.AddCmd;
import cheme.ProcessModel.Cmds.DeleteCmd;
import cheme.ProcessModel.Cmds.MoveCmd;
import cheme.ProcessModel.Equations.Equation;
import cheme.ProcessModel.Equations.EquationField;
import cheme.ProcessModel.Equations.EquationPalette;
import cheme.ProcessModel.Equations.IPaletteField;
import cheme.ProcessModel.ProcessUnits.Streams.Tags.ITagComponent;
import cheme.ProcessModel.ProcessUnits.Streams.Tags.TagComponent;
import cheme.ProcessModel.Table.IField;
import cheme.ProcessModel.Table.ITextModel;

public class PolicyEquationLayout extends ToolbarLayoutEditPolicy
{
	@Override
	public Command getCommand(Request request)
	{		
		if(REQ_ADD.equals(request.getType()))
		{
			return super.getCommand(request);
		}
		
		return super.getCommand(request);
	}
	
	/*
	 * Commands that may reasonably yields target feedback:
	 * REQ_ADD
	 * REQ_CLONE
	 * REQ_MOVE
	 * REQ_RESIZE_CHILDREN
	 * REQ_CREATE
	 */
	@Override
	protected void showLayoutTargetFeedback(Request request)
	{
		boolean allowShow = false;
		
		if(REQ_CREATE.equals(request.getType()))
		{
			CreateRequest createReq = (CreateRequest)request;
			if(createReq.getNewObject() instanceof TagComponent || createReq.getNewObject() instanceof IField)
			{
				allowShow = true;
			}
		}
		else if(REQ_ADD.equals(request.getType()) || REQ_MOVE.equals(request.getType()))
		{
			ChangeBoundsRequest boundsReq = (ChangeBoundsRequest)request;
			List<GraphicalEditPart> parts = boundsReq.getEditParts();
			
			if(parts.size() > 0)
			{
				/*
				 * All model elements have to be of TagComponent type
				 */
				
				allowShow = true;
				
				for(GraphicalEditPart part : parts)
				{
					allowShow &= (part.getModel() instanceof ITagComponent || part.getModel() instanceof IField);
				}			
			}
		}
		
		if(allowShow)
		{
			super.showLayoutTargetFeedback(request);
		}
	}

	@Override
	protected Command createAddCommand(EditPart child, EditPart after)
	{
		/*
		 * need to take into account that the afterChild could be null and will need to add the child to the end.
		 */
		
		CompoundCommand cmd = new CompoundCommand();

		IChild moveChild = (IChild)child.getModel();
		IParent originalParent = moveChild.getParent();
		IParent newParent = (IParent)getHost().getModel();
//		IParent parent = (IParent)getHost().getModel();
		
		int newIndex = -1;
		
		if (after != null)
		{
			newIndex = getHost().getChildren().indexOf(after);
		}
		
		/*
		 * If we are dropping a tag, we need to grab the label, and return a create (AddCmd)
		 */
		if(moveChild instanceof ITagComponent)
		{
			EquationField newField = new EquationField(newParent, ((ITagComponent)moveChild).getLabel());
			ITextModel firstChild = (ITextModel)newParent.getChildren().get(0);
			
			if(newParent.getChildren().size() == 1 && firstChild.getText().isEmpty())
			{
				newIndex = 0;
			}

			cmd.add(new AddCmd(newField, newParent, newIndex));

		}
		else if(moveChild instanceof IPaletteField)
		{
			String label = ((IPaletteField)moveChild).getText();
			EquationField newField = new EquationField(newParent, label);
			cmd.add(new AddCmd(newField, newParent, newIndex));
		}
		else if(moveChild instanceof Equation || moveChild instanceof TooltipModel 
				|| moveChild instanceof EquationPalette || moveChild instanceof SolvabilityStatus)
		{
			// Do nothing
			// Added this else if block to stop the movement of an equation
			// Now user can not move one equation into another
		}
		else
		{
			cmd.add(new MoveCmd(moveChild, originalParent, newParent, newIndex));

			/*
			 * Are we moving the last element in the originalParent? If so, delete the
			 * list too.
			 */
			
			if(1 == originalParent.getChildren().size())
			{
				cmd.add(new DeleteCmd((IChild)originalParent));
			}
		}
		
		return cmd.unwrap();
	}

	@Override
	protected Command createMoveChildCommand(EditPart child, EditPart after)
	{		
		int newIndex = -1;
		
		if (after != null)
		{
			newIndex = getHost().getChildren().indexOf(after);
		}
		
		IChild childModel = (IChild) child.getModel();
		IParent parent = (IParent) getHost().getModel();
		
		MoveCmd command = new MoveCmd(childModel, parent, newIndex);
		
		return command;
	}

	@Override
	protected Command getCreateCommand(CreateRequest request)
	{
		return null;
	}

	@Override
	protected Rectangle getAbsoluteBounds(GraphicalEditPart ep)
	{
		Rectangle bounds = ep.getContentPane().getBounds().getCopy();
		ep.getContentPane().translateToAbsolute(bounds);
		return bounds;
	}
	
}
